package com.netflexitysolutions.amazonws.sdb.orm.metadata;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;

/**
 * @author Max Fedorov
 *
 * Contains all the objects and attributes that belong to 
 * &lt;simpledb-mapping&gt; XML element.
 */
public class SimpleDBMapping{
	
	private Map<String, ItemMetadata> itemMetadata = new HashMap<String, ItemMetadata>(10);
	private Map<String, Map<String, ItemMetadata>> itemMetadataByDomain = new HashMap<String, Map<String, ItemMetadata>>(10);
	private Map<String, String> queries = new HashMap<String, String>();
	
	/**
	 * @return
	 */
	public List<String> getQueries() {
        return Collections.unmodifiableList(new ArrayList<String>(this.queries.values()));
	}
	
	public Map<String, String> getQueriesMap() {
		return  Collections.unmodifiableMap(new HashMap<String, String>(queries));
	}
    
	/**
	 * @param name
	 * @param value
	 */
	public void addQuery(String name, String value) {
		if(StringUtils.isBlank(name)){
			throw new MetadataException("'name' is a required attribute of <query>, which must be supplied for " + this.getClass().getName());
		}
		this.queries.put(name, value);
	}
    
	/**
	 * @param name
	 * @return
	 */
	public String getQueryByName(String name) {
	    if(StringUtils.isNotBlank(name)){
	        return (String)queries.get(name);
	    }
	    return null;
	}
    
	/**
	 * @return
	 */
	public List<ItemMetadata> getItemMetadata(){
		return Collections.unmodifiableList(new ArrayList<ItemMetadata>(itemMetadata.values()));
	}
    
	/**
	 * @param itemMeta
	 */
	public void addItemMetadata(ItemMetadata itemMeta) {
		itemMeta.setMapping(this);
		this.itemMetadata.put(itemMeta.getClassName(), itemMeta);
		
		/*Map<String, ItemMetadata> domainItems = this.itemMetadataByDomain.get(itemMeta.getDomainName().toLowerCase());
		if(domainItems == null){
			domainItems = new HashMap<String, ItemMetadata>();
			this.itemMetadataByDomain.put(itemMeta.getDomainName().toLowerCase(), domainItems);
		}
		domainItems.put(itemMeta.getClassName(), itemMeta);*/
	}
    
	/**
	 * @param domainName
	 * @return
	 */
	public List<ItemMetadata> getItemMetadataByDomain(String domainName){
		Map<String, ItemMetadata> domainItems = itemMetadataByDomain.get(domainName.toLowerCase());
		if(domainItems == null) return null;
		return Collections.unmodifiableList(new ArrayList<ItemMetadata>(domainItems.values()));
	}
	
	/**
	 * @param domainName
	 * @param className
	 * @return
	 */
	public ItemMetadata getItemMetadata(String domainName, String className){
		Map<String, ItemMetadata> domainItems = itemMetadataByDomain.get(domainName.toLowerCase());
		if(domainItems == null) return null;
		return domainItems.get(className);
	}
	
	/**
	 * @param clazz
	 * @return
	 */
	public ItemMetadata getItemMetadataByClass(Class<?> clazz) {
	    return itemMetadata.get(clazz.getName());
	}
}
